package com.hhh.springai_test.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hhh.springai_test.common.ErrorCode;
import com.hhh.springai_test.constant.BookConstant;
import com.hhh.springai_test.exception.BusinessException;
import com.hhh.springai_test.model.dto.book.AddBookDTO;
import com.hhh.springai_test.model.dto.book.BookQueryRequest;
import com.hhh.springai_test.model.dto.book.CategoryStatisticsDTO;
import com.hhh.springai_test.model.dto.book.UpdateBookDTO;
import com.hhh.springai_test.model.po.Book;
import com.hhh.springai_test.model.po.BookCategory;
import com.hhh.springai_test.service.BookCategoryService;
import com.hhh.springai_test.service.BookService;
import com.hhh.springai_test.mapper.BookMapper;
import com.hhh.springai_test.service.UserService;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

/**
* @author 29915
* @description 针对表【book(图书信息表)】的数据库操作Service实现
* @createDate 2025-02-01 15:58:19
*/
@Service
public class BookServiceImpl extends ServiceImpl<BookMapper, Book>
    implements BookService{

    @Resource
    private BookCategoryService bookCategoryService;

    @Override
    public long addBook(AddBookDTO addBookDTO, String loginUserId) {
        if (addBookDTO == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空");
        }
        // 校验图书名是否已存在
        String bookName = addBookDTO.getBookname();
        if (StringUtils.isBlank(bookName)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "图书名称不能为空");
        }
        QueryWrapper<Book> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("bookname", bookName);
        long count = this.count(queryWrapper);
        if (count > 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "图书名称已存在");
        }
        QueryWrapper<Book> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("isbn", addBookDTO.getIsbn());
        long count1 = this.count(queryWrapper2);
        if (count1 > 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "图书ISBN已存在");
        }
        Book book = new Book();
        BeanUtils.copyProperties(addBookDTO, book);
        List<String> categorycode = new ArrayList<>(addBookDTO.getCategorycode());
        categorycode.add("all");
        Set<String> uniqueCategoryCodes = new HashSet<>();
        Set<String> duplicateCategoryCodes = new HashSet<>();
        for (String s : categorycode) {
            if (!uniqueCategoryCodes.add(s)) { // 添加失败，说明是重复的
                duplicateCategoryCodes.add(s);
            }
        }
        if (!duplicateCategoryCodes.isEmpty()) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "重复的分类编码: " + String.join(", ", duplicateCategoryCodes));
        }
        List<String> validCategoryCodes = new ArrayList<>();
        for (String s : categorycode) {
            QueryWrapper<BookCategory> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("categorycode", s);
            BookCategory bookCategory = bookCategoryService.getOne(queryWrapper1);
            if (bookCategory == null) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "分类编码不存在");
            }
            validCategoryCodes.add(s);
        }
        // 使用 Hutool 转换为 JSON 格式的字符串
        String jsonCategoryCodes = JSONUtil.toJsonStr(validCategoryCodes);
        book.setCategorycode(jsonCategoryCodes);
        // 设置默认属性
        book.setCreateuser(Long.valueOf(loginUserId));
        book.setAipromptid(BookConstant.DEFAULT_AI_PROMPT_ID);
        boolean result = this.save(book);
        if (!result) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "添加图书失败");
        }
        return book.getId();
    }

    @Override
    public boolean deleteBook(long id) {
        if (id <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "图书ID不合法");
        }
        QueryWrapper<Book> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", id);
        long count = this.count(queryWrapper);
        if (count == 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "图书不存在");
        }
        return this.removeById(id);
    }

    @Override
    public boolean updateBook(UpdateBookDTO updateBookDTO) {
        if (updateBookDTO == null || updateBookDTO.getId() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 校验图书是否存在
        Book oldBook = this.getById(updateBookDTO.getId());
        if (oldBook == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 校验新图书名是否与其他图书重复
        String newBookName = updateBookDTO.getBookname();
        if (StringUtils.isNotBlank(newBookName)) {
            QueryWrapper<Book> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("bookname", newBookName);
            long count = this.count(queryWrapper);
            if (count > 0) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "图书名称已存在");
            }
        }
        QueryWrapper<Book> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("isbn", updateBookDTO.getIsbn());
        long count1 = this.count(queryWrapper2);
        if (count1 > 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "图书ISBN已存在");
        }
        Book book = new Book();
        BeanUtils.copyProperties(updateBookDTO, book);
        List<String> categorycode = new ArrayList<>(updateBookDTO.getCategorycode());
        categorycode.add("all");
        Set<String> uniqueCategoryCodes = new HashSet<>();
        Set<String> duplicateCategoryCodes = new HashSet<>();
        for (String s : categorycode) {
            if (!uniqueCategoryCodes.add(s)) { // 添加失败，说明是重复的
                duplicateCategoryCodes.add(s);
            }
        }
        if (!duplicateCategoryCodes.isEmpty()) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "重复的分类编码: " + String.join(", ", duplicateCategoryCodes));
        }
        List<String> validCategoryCodes = new ArrayList<>();
        for (String s : categorycode) {
            QueryWrapper<BookCategory> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("categorycode", s);
            BookCategory bookCategory = bookCategoryService.getOne(queryWrapper1);
            if (bookCategory == null) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "分类编码不存在");
            }
            validCategoryCodes.add(s);
        }
        // 使用 Hutool 转换为 JSON 格式的字符串
        String jsonCategoryCodes = JSONUtil.toJsonStr(validCategoryCodes);
        book.setCategorycode(jsonCategoryCodes);
        return this.updateById(book);
    }

    @Override
    public Page<Book> listBookByPage(BookQueryRequest bookQueryRequest) {
        if (bookQueryRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 获取分页参数，并设置默认值
        long current = Math.max(bookQueryRequest.getCurrent(), 1);
        long pageSize = Math.max(bookQueryRequest.getPageSize(), 1);
        
        String bookName = bookQueryRequest.getBookname();
        String bookAuthor = bookQueryRequest.getBookauthor();
        List<String> categoryCodes = bookQueryRequest.getCategorycode();
        
        // 创建分页对象
        Page<Book> page = new Page<>(current, pageSize);
        QueryWrapper<Book> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("isdelete", 0); // 只查询未删除的图书
        
        // 添加查询条件
        if (StringUtils.isNotBlank(bookName)) {
            queryWrapper.like("bookname", bookName);
        }
        if (StringUtils.isNotBlank(bookAuthor)) {
            queryWrapper.like("bookauthor", bookAuthor);
        }
        
        // 处理分类编码查询
        if (categoryCodes != null && !categoryCodes.isEmpty()) {
            queryWrapper.and(wrapper -> {
                for (String categoryCode : categoryCodes) {
                    // 使用 LIKE 查询，确保分类编码被双引号包围
                    wrapper.or().like("categorycode", "\"" + categoryCode + "\"");
                }
            });
        }
        
        // 添加排序
        queryWrapper.orderByDesc("createtime");
        
        // 执行分页查询并返回结果
        return this.page(page, queryWrapper);
    }

    @Override
    public List<CategoryStatisticsDTO> getCategoryStatistics() {
        // 获取所有分类
        List<BookCategory> categories = bookCategoryService.list();
        
        // 获取所有图书的分类编码
        List<Book> books = this.list();
        
        // 统计每个分类的图书数量
        Map<String, Long> countMap = new HashMap<>();
        
        for (Book book : books) {
            String categoryCodes = book.getCategorycode();
            if (StringUtils.isNotBlank(categoryCodes)) {
                // 移除方括号并分割字符串
                String[] codes = categoryCodes.replace("[", "")
                        .replace("]", "")
                        .replace("\"", "")
                        .split(",");
                
                // 统计每个分类的数量
                for (String code : codes) {
                    code = code.trim();
                    countMap.merge(code, 1L, Long::sum);
                }
            }
        }
        
        // 使用AtomicLong来生成递增的ID
        AtomicLong idGenerator = new AtomicLong(1);
        
        // 生成最终结果
        return categories.stream()
            .map(category -> {
                CategoryStatisticsDTO dto = new CategoryStatisticsDTO();
                dto.setId(idGenerator.getAndIncrement()); // 设置递增的ID
                dto.setCategorycode(category.getCategorycode());
                dto.setCategorynamezh(category.getCategorynamezh());
                dto.setBookCount(countMap.getOrDefault(category.getCategorycode(), 0L));
                return dto;
            })
            .collect(Collectors.toList());
    }
}